package net.zui.entity;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import net.zui.comp.ZBase;
import net.zui.enume.MouseState;
import net.zui.error.IdDuplicateException;
import net.zui.util.UCollision;
import net.zui.util.UComm;
/**
    * 组件管理类
 * <br /><br />
 * <b>作者:</b>张天文 <br />
 * <b>日期:</b>2021年10月20日 下午3:18:18<br />
 * @date
 */
public class ZBaseManager{
	private static final Map<String,Integer> idMap=new ConcurrentHashMap<>();
	private List<ZBase> list=new ArrayList<ZBase>();
	private Map<String,ZBase> map=new HashMap<>();
	private volatile boolean change=false;
	private int width,height;
	private ZBase focus,hover;

	public synchronized static String getId(Class<?> c) {
		String className=c.getName();
		Integer integer = idMap.get(className);
		integer=integer==null?1:++integer;
		idMap.put(className, integer);
		return c.getSimpleName()+integer;
	}

	public ZBaseManager() { }

	public void add(ZBase base) throws IdDuplicateException {
		if(map.containsKey(base.getId())) {
			throw new IdDuplicateException(UComm.arrToStr("id:",base.getId(),"已经存在!"));
		}
		list.add(base);
		map.put(base.getId(), base);
		change=true;
	}
	
	public ZBase findById(String id) {
		return map.get(id);
	}
	
	public List<ZBase> findByType(Class<? extends ZBase> type){
		List<ZBase> tmpList=new ArrayList<>();
		for(ZBase base:list) {
			if(type.isAssignableFrom(base.getClass()))tmpList.add(base);
		}
		return tmpList;
	}
	
	public ZBase remove(String id) {
		ZBase remove = map.remove(id);
		if(remove==null)return remove;
		list.remove(remove);
		change=true;
		return remove;
	}

	public List<ZBase> bases() {
		if(change) {
			change=false;
			Collections.sort(list);	
		}
		return new ArrayList<>(list);
	}

	public ZBase findByPoint(int x, int y) {
		if(change) {
			change=false;
			Collections.sort(list);	
		}
		ZBase base;
		for(int i=list.size()-1;i>=0;i--) {
			base=list.get(i);
			if(UCollision.inBox(x, y, base))return base;
		}
		return null;
	}
	
	public ZBase findByPointAble(int x, int y) {
		if(change) {
			change=false;
			Collections.sort(list);	
		}
		ZBase base;
		for(int i=list.size()-1;i>=0;i--) {
			base=list.get(i);
			if(!base.getAble())continue;
			if(UCollision.inBox(x, y, base))return base;
		}
		return null;
	}

	public List<ZBase> findByPointDeep(int x, int y) {
		if(change) {
			change=false;
			Collections.sort(list);	
		}
		List<ZBase> tmpList=new ArrayList<>();
		ZBase base;
		for(int i=list.size()-1;i>=0;i--) {
			base=list.get(i);
			if(UCollision.inBox(x, y, base))tmpList.add(base);
		}
		return tmpList;
	}

	public void setChange() {
		change=true;		
	}

	public ZBase get(String id) {
		return map.get(id);
	}

	public int getWidth() {
		return width;
	}

	public int getHeight() {
		return height;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public ZBase getFocus() {
		return focus;
	}

	public void setFocus(ZBase focus) {
		if(this.focus==focus)return;
		if(focus==null) {
			if(this.focus!=null) {
				this.focus.lostFocus();
				this.focus=null;
			}
		}else {
			focus.setFocus();
			if(this.focus!=null)this.focus.lostFocus();
			this.focus = focus;
		}
	}
	
	public ZBase getHover() {
		return hover;
	}

	public void setHover(ZBase hover) {
		if(this.hover!=null)this.hover.setMouseState(MouseState.mouseOut);
		if(hover!=null) hover.setMouseState(MouseState.mouseIn);
		this.hover = hover;
	}
}
